#include "FCFS_Scheduler.h"
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

FCFS_Scheduler::FCFS_Scheduler()
{
}


void FCFS_Scheduler::runScheduler()
{
	int endTimeOfPreviousProcess = 0;
	vector<Process>::reverse_iterator process;

	//sort processes in descending order
	sortProcesses();

	//iterate through the processList in reverse order
	for(process = processList.rbegin(); process != processList.rend(); process++)
	{
		if(process == processList.rbegin())
		{
			//first process came in at time zero
			if((*process).getArrivalTIme() == 0)
			{
				(*process).setEndTime((*process).getCPU_Burst());
				(*process).setStartTime((*process).getArrivalTIme());
			}
			else //first process came in after time 0
			{
				(*process).setStartTime((*process).getArrivalTIme());
				(*process).setEndTime((*process).getCPU_Burst() + (*process).getArrivalTIme());
				
			}
		}
		else
		{
			//process came in after the previos process finished
			if((*process).getStartTime() > endTimeOfPreviousProcess)
			{
				(*process).setStartTime((*process).getArrivalTIme());
				(*process).setEndTime((*process).getStartTime() + (*process).getCPU_Burst());
			}
			else
			{ //process came in before at the same time the previous process finished
				(*process).setEndTime(endTimeOfPreviousProcess + (*process).getCPU_Burst());
				(*process).setStartTime(endTimeOfPreviousProcess);
			}
		}

		endTimeOfPreviousProcess = (*process).getEndTime();
		//cout << "Start Time: " << (*process).getStartTime() << "        End Time: " << (*process).getEndTime() << "       Burst: " << (*process).getCPU_Burst() << endl;
		}
}

Process FCFS_Scheduler::getNextProcess()
{
	Process nextJob = processList.back();
	processList.pop_back();
	return nextJob;
}

bool FCFS_Scheduler::compareStartTime(vector<Process>::iterator positionOne, vector<Process>::iterator positionTwo)
{
	//cout << "values: " << (*positionOne)->getStartTime() << "    " << (*positionTwo)->getStartTime();
	return (*positionOne).getStartTime() < (*positionTwo).getStartTime();
}

void FCFS_Scheduler::sortProcesses()
{
	vector<Process>::iterator end, positionOne, positionTwo;
	bool swapped = true;

	end = processList.end();

	do
	{
		swapped = false;
		positionTwo = ++processList.begin();
		for(positionOne = processList.begin(); positionTwo != end; positionOne++, positionTwo++)
		{
			if(compareStartTime(positionOne, positionTwo))
			{
				swap(*positionOne, *positionTwo);
				swapped = true;
			}
		}
	}while(swapped);
}

void FCFS_Scheduler::printList()
{
	vector<Process>::iterator begin, end, index;

	begin = processList.begin();
	end = processList.end();

	for(index = begin; index < end; index++)
		cout << (*index).getStartTime() << "   ";
}
